<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Mouse Stroke - Help</title>
<link type="text/css" rel="stylesheet" href="options.css" />
<script type="text/javascript" src="essentials.js"></script>
<script type="text/javascript" src="stroke.js"></script>
<script type="text/javascript">
/* the id of the selected stroke command */
var _stroke_id = null;

/* default configuration */
var _cfg, _defcfg = JSON.parse(localStorage.getItem('def_config'));

/* port to the background page */
var _port = chrome.extension.connect({name: 'stroke.html-config'});

/* convert id to a readable label */
var id2label = function(id) {
	/* replace hyphens to spaces, then capitalize the first letter */
	return id.replace(/\-/g, ' ').replace(/\w+/g, function(s) {
		return s.charAt(0).toUpperCase() + s.substring(1);
	});
}

/* pack stroke sequence into a space separated string */
var pack = function(seq) {
	return (!!seq && seq.join) ? seq.join(' ').trim() : '';
}

/* construct the config form */
var construct = function(cfg)
{
	var tb = $get('stroke-tbody'), tr, td, input, set, unset, cat;

	/* restore options */
	$get('trigger').value = cfg.trigger;
	$get('timeout').value = cfg.timeout;
	$get('minstep').value = cfg.minstep;
	$get('trail').value = cfg.trail;
	$get('suppress').checked = !!cfg.suppress;

	/* stroke categories will be flatted for easy referring */
	cfg.strokes = {};

	/* restore stroke settings */
	for (key in cfg.categories) {
		tr = $create('tr');
		/* categories */
		tr.appendChild($create('th', {
			className: 'title',
			colSpan: 2,
			innerHTML: id2label(key)
		}));
		tb.appendChild(tr);

		/* strokes */
		cat = cfg.categories[key];
		for (key in cat) {
			tr = $create('tr');
			/* label */
			tr.appendChild($create('td', {
				className: 'label',
				innerHTML: id2label(key)
			}));
			/* input field */
			input = $create('input', {
				id: key,
				type: 'text',
				disabled: true,
				className: 'stroke-field',
				value: pack(cat[key])
			});
			/* set button */
			set = $create('button', {
				className: 'set-stroke-btn',
				'for': key,
				innerHTML: 'Define'
			});
			set.addEventListener('click', set_stroke, false);
			/* unset button */
			unset = $create('button', {
				className: 'unset-stroke-btn',
				'for': key,
				innerHTML: 'Earse'
			});
			unset.addEventListener('click', unset_stroke, false);

			td = $create('td', { className: 'field' });
			td.appendChild(input);
			td.appendChild(set);
			td.appendChild(unset);
			tr.appendChild(td);
			tb.appendChild(tr);

			/* flat categories, all operations on cfg.strokes
			 * should done by reference, so that changes can be
			 * reflected on their counterparts in cfg.categories */
			cfg.strokes[key] = cat[key];
		}
	}

	/* bind restore/save button listener */
	$get('restore').addEventListener('click', restore, false);
	$get('save').addEventListener('click', harvest, false);
}

/* save settings */
var harvest = function()
{
	var i, inputs = $get('stroke-tbody').getElementsByClassName('stroke-field');

	_cfg.trigger = parseInt($get('trigger').value);
	_cfg.timeout = parseInt($get('timeout').value);
	_cfg.minstep = parseInt($get('minstep').value);
	_cfg.trail = $get('trail').value;
	_cfg.suppress = $get('suppress').checked;

	/* save locally */
	localStorage.setItem('config', JSON.stringify(_cfg));
	/* tell the background page to reload config */
	_port.postMessage('reload');
	location.reload(true);
}

/* restore default settings */
var restore = function()
{
	localStorage.removeItem('config');
	_port.postMessage('reload');
	location.reload(true);
}

/* event handler for setting stroke */
var set_stroke = function(e)
{
	/* set the command id, so the stroke listener knows which stroke
	 * should be set */
	_stroke_id = e.target['for'];
	/* display the overlay, waiting for input */
	$get('which-stroke').innerHTML = id2label(_stroke_id);
	$show('overlay');
}

/* event handler for removing stroke */
var unset_stroke = function(e) {
	var k = e.target['for'];
	/* unset the stroke */
	$get(k).value = '';
	/* empty the stroke array */
	_cfg.strokes[k].splice(0, _cfg.strokes[k].length);
}

window.addEventListener('load', function() {
	/* fallback to _defcfg if _cfg from local storage is empty */
	try {
		if (!(_cfg = JSON.parse(localStorage.getItem('config')))) {
			_cfg = _defcfg;
		}
	} catch (ex) {
		console.error(ex);
		_cfg = _defcfg;
	}
	construct(_cfg);
	_port.postMessage('pull-config');

	$get('cancel-btn').addEventListener('click', function() {
		/* cancel setting stroke */
		$hide('overlay');
		_stroke_id = null;
	}, false);
});

/* listen to the stroke detecting script */
document.addEventListener('set-stroke-event', function(ev) {
	var k, input = $get(_stroke_id), strokes = ev.path.strokes, seq = pack(strokes);

	if (input) {
		/* check duplicates */
		for (k in _cfg.strokes) {
			if (_stroke_id != k && seq == pack(_cfg.strokes[k])) {
				if (confirm('"' + seq + '" has been assigned to [' + id2label(k) + '], overwrite?')) {
					$get(k).value = '';
					/* clear conflicted settings */
					_cfg.strokes[k].splice(0, _cfg.strokes[k].length);
					break;
				} else {
					return;
				}
			}
		}
		input.value = seq;
		/* operate on the array reference */
		var ref = _cfg.strokes[_stroke_id]
		ref.splice.apply(ref, [0, ref.length].concat(strokes));
	}
	$hide('overlay');
	_stroke_id = null;
}, false);
</script>
<body>

<div id="overlay" class="overlay hidden">
 <h2>
  Waiting stroke for: [<span id="which-stroke"></span>]<br/>
  <button id="cancel-btn">Cancel</button>
 </h2>
</div>

<div id="root" class="root">
 <h1>Mouse Stroke (<a href="http://code.google.com/p/chrome-mouse-stroke/">Homepage</a>)</h1>

 <p>
  This is a Google Chrome extension which enables
  <a href="http://en.wikipedia.org/wiki/Mouse_gesture">mouse strokes</a>
  (also known as mouse gestures) in the browser. With this extension, you can
  perform common tasks by simply moving your mouse.
 </p>

 <ol class="eye-catcher">
  <li>Please report bugs and feature requests at the
   <a href="http://code.google.com/p/chrome-mouse-stroke/issues/list">support page</a>.
  </li>
  <li>Linux / Mac users, you have to use LEFT mouse button as the stroke trigger
   (not a perfect solution), the reason is explained
   <a href="http://code.google.com/p/chromium/issues/detail?id=26465">here</a>.
   I've posted a possible fix at
   <a href="http://code.google.com/p/chromium/issues/detail?id=28226">Chromium's issue list</a>,
   but I'm not holding my breath for it.
  </li>
  <li>Note that due to the security restrictions of Google Chrome extension system,
   the extension works in regular web pages only (any <code>http://</code> or
   <code>https://</code> sites), which means your strokes won't work in pages
   like <code>chrome://newtab</code> or <code>chrome://extensions</code>.
  </li>
  <li><strong><em>Please notice</em></strong>:
   Mouse Stroke needs a nice icon, I'm not good at designing, see the current
   one ;), so if you'd like to help, please post your design
   <a href="http://code.google.com/p/chrome-mouse-stroke/issues/detail?id=15">here</a>.
   You can also email it to me if you prefer, the address is
   <code>[<a href="http://code.google.com/u/vigacmoe/">my-user-name</a>]@gmail.com</code>.
   Designs of the options page are also welcomed. Thank you.<br/>
   PS: you will not get any money payback. 
  </li>
 </ol>

 <table id="option-table" class="option-table" cellpadding="0" cellspacing="0" border="0">

  <tbody id="option-tbody">
   <tr>
    <th class="title" colspan="2">Options</th>
   </tr>
   <tr>
    <td class="label">Trigger</td>
    <td class="field">
     <select id="trigger">
      <option value="0">Left Mouse Button</option>
      <!--option value="1">Middle Mouse Button</option-->
      <option value="2">Right Mouse Button</option>
     </select>
    </td>
   </tr>
   <tr>
    <td class="label">
     Stroke Timeout (Milliseconds)<br/>
     <em><sub>
      Try 1000 if you feel difficult to perform strokes
     </sub></em>
    </td>
    <td class="field">
     <input id="timeout" type="text"/>
    </td>
   </tr>
   <tr>
    <td class="label">Minimum Step (Pixels)</td>
    <td class="field">
     <input id="minstep" type="text"/>
    </td>
   </tr>
   <tr>
    <td class="label">Draw Trails</td>
    <td class="field">
     <select id="trail">
      <option value="">none</option>
      <option value="black" style="color:black">black</option>
      <option value="red" style="color:red">red</option>
      <option value="green" style="color:green">green</option>
      <option value="yellow" style="color:yellow">yellow</option>
      <option value="blue" style="color:blue">blue</option>
      <option value="magenta" style="color:magenta">magenta</option>
      <option value="cyan" style="color:cyan">cyan</option>
     </select>
    </td>
   </tr>
   <tr>
    <td class="label">Do nothing if I'm holding Alt</td>
    <td class="field">
     <input id="suppress" type="checkbox"/>
    </td>
   </tr>
  </tbody>

  <tbody id="stroke-tbody">
  </tbody>

  <tbody>
   <tr>
    <th colspan="2">
     <button id="restore">Restore to default</button>
     <button id="save">Save</button>
    </th>
   </tr>
  </tbody>

 </table>

</div>
</body>
</html>